/**
 * SPDX-FileCopyrightText: 2023-2025 Sangfor Technologies Inc.
 * SPDX-License-Identifier: Mulan PSL v2
 */
<template>
    <div>
        <div class="sfv-transfer flex">
            <div class="sfv-transfer-left">
                <sf-grid :style="leftStyle">
                    <div class="sfv-transfer-toolbar">
                        <sf-toolbar>
                            <sf-checkbox
                                v-model="checkAllLeft"
                                :check-part="true"
                                class="sfv-transfer-title">
                                {{ leftTitle }} ({{ leftCount || 0 }})
                            </sf-checkbox>
                        </sf-toolbar>
                    </div>

                    <div class="sfv-transfer-body">
                        <sf-table 
                            ref="leftTable"
                            :options="tableOptions"
                            default-height="100%"
                            @selectionchange="_checkLeftChange">
                            <sf-table-column data-index="label" />
                        </sf-table>
                    </div>
                </sf-grid>
            </div>
            <div class="sfv-transfer-handler-list">
                <div class="sfv-transfer-handler-item m-b18">
                    <div class="sfv-transfer-handler">
                        <div class="sfv-transfer-toright"
                             :class="{disabled: disabledToRight}"
                             sfv
                             @click="_clickToRight">
                            <i class="sf-comp-iconfont icon-comp-arrow2-right"></i>
                        </div>
                        <div class="sfv-transfer-toleft"
                             :class="{disabled: disabledToLeft}"
                             sfv
                             @click="_clickToLeft">
                            <i class="sf-comp-iconfont icon-comp-arrow2-left"></i>
                        </div>
                    </div>

                    <div class="sfv-transfer-right">
                        <sf-grid :style="rightStyle">
                            <div class="sfv-transfer-toolbar">
                                <sf-toolbar>
                                    <sf-checkbox
                                        v-model="checkAllRight"
                                        :check-part="true"
                                        class="sfv-transfer-title">
                                        {{ rightTitle }} ({{ rightCount || 0 }})
                                    </sf-checkbox>
                                    <div class="sfv-transfer-actions">
                                        <span
                                            class="sfv-transfer-action"
                                            @click="_clearRight">
                                            清空
                                        </span>
                                    </div>
                                </sf-toolbar>
                            </div>
                            <div class="sfv-transfer-body">
                                <sf-table 
                                    ref="rightTable"
                                    :options="tableRightOptions"
                                    default-height="100%"
                                    @selectionchange="_checkRightChange">
                                    <sf-table-column data-index="label" />
                                    <!-- @selectionchange="_checkChange" -->
                                </sf-table>
                            </div>
                        </sf-grid>
                    </div>
                </div>
                <div class="sfv-transfer-handler-item">
                    <div class="sfv-transfer-handler">
                        <div class="sfv-transfer-toright"
                             :class="{disabled: disabledToRightSecond}"
                             sfv
                             @click="_clickToRightSecond">
                            <i class="sf-comp-iconfont icon-comp-arrow2-right"></i>
                        </div>
                        <div class="sfv-transfer-toleft"
                             :class="{disabled: disabledToLeftSecond}"
                             sfv
                             @click="_clickToLeftSecond">
                            <i class="sf-comp-iconfont icon-comp-arrow2-left"></i>
                        </div>
                    </div>

                    <div class="sfv-transfer-right">
                        <sf-grid :style="rightStyle">
                            <div class="sfv-transfer-toolbar">
                                <sf-toolbar>
                                    <sf-checkbox
                                        v-model="checkAllRightSecond"
                                        :check-part="true"
                                        class="sfv-transfer-title">
                                        {{ rightTitleSecond }} ({{ rightCountSecond || 0 }})
                                    </sf-checkbox>
                                    <div class="sfv-transfer-actions">
                                        <span
                                            class="sfv-transfer-action"
                                            @click="_clearRightSecond">
                                            清空
                                        </span>
                                    </div>
                                </sf-toolbar>
                            </div>
                            <div class="sfv-transfer-body">
                                <sf-table 
                                    ref="rightTableSecond"
                                    :options="tableRightOptionsSecond"
                                    default-height="100%"
                                    @selectionchange="_checkRightChangeSecond">
                                    <sf-table-column data-index="label" />
                                </sf-table>
                            </div>
                        </sf-grid>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<style lang="less">
    .sfv-transfer{
        &.flex{
            display: flex;
             .sfv-checkbox-wrap+label{
                    margin-left: 15px;
                }
            .sfv-transfer .sfv-transfer-toolbar .sfv-transfer-title {
                margin-top: -12px;
                margin-left: 3px;
               
                
            }
        }
        .m-b18{
            margin-bottom: 18px;
        }
    }
</style>

<script>
    import { extend } from '@sxf/sf-vue-component/src/util/extend';
    import uniqBy from 'lodash/uniqBy';
    import cloneDeep from 'lodash/cloneDeep';
    import differenceBy from 'lodash/differenceBy';

    /**
     * Created by hjh on 2019/6/13.
     */

    export default {
        props: {
            defaultWidth:{
                default:'320'
            },
            leftHeight:{
                default:'520'
            },
            rightHeight:{
                default:'250'
            },
            leftTitle:{
                default:_('选择字段')
            },
            rightTitle:{
                default:_('已选')
            },
            rightTitleSecond:{
                default:_('已选')
            },
            leftData:{
                default:()=>[],
                type:Array
            },
            rightData:{
                default:()=>[],
                type:Array
            },
            rightDataSecond:{
                default:()=>[],
                type:Array
            },
            initData:{
                default:()=>[],
                type:Array
            }
        },

        data () {
            return {
                idProperty:'label',
                checkAllLeft:'checkNone',
                checkAllRight:'checkNone',
                checkAllRightSecond:'checkNone',
                allData: [],
                checkedData: [],
                checkedDataSecond: [],
                disabledToLeft: true,
                disabledToRight: true,
                disabledToLeftSecond: true,
                disabledToRightSecond: true,
                leftCount:0,
                rightCount:0,
                rightCountSecond:0,
                tableOptions: {
                     bufferView: false,
                    selectionMode: 'multi',
                    rowHeight: 32,
                    headerHide: true,
                    idProperty: 'label'
                },
                tableRightOptions: {
                    selectionMode: 'multi',
                    rowHeight: 32,
                    data: [],
                    idProperty: 'label',
                    headerHide: true
                },
                tableRightOptionsSecond: {
                    selectionMode: 'multi',
                    rowHeight: 32,
                    data: [],
                    idProperty: 'label',
                    headerHide: true
                }
            };
        },
         created () {
            this.checkedDataMap = new Map();
            this.checkedDataMapSecond = new Map();
        },
         computed: {
            leftContainer () {
                return this.$refs.leftTable;
            },
            rightContainer () {
                return this.$refs.rightTable;
            },
            rightContainerSecond () {
                return this.$refs.rightTableSecond;
            },
            leftStyle () {
                return {
                    width: this.defaultWidth + 'px',
                    height: this.leftHeight + 'px'
                };
            },

            rightStyle () {
                return {
                    width: this.defaultWidth + 'px',
                    height:this.rightHeight + 'px'
                };
            }

           
        },
        watch: {
            checkAllLeft (v) {
                if (v === 'checkAll') {
                    this.$refs.leftTable.selectCurrentPage();
                } else if (v === 'checkNone') {
                    this.$refs.leftTable.unSelectCurrentPage();
                }
            },

            checkAllRight (v) {
                if (v === 'checkAll') {
                    this.$refs.rightTable.selectCurrentPage();
                } else if (v === 'checkNone') {
                    this.$refs.rightTable.unSelectCurrentPage();
                }
            },
            checkAllRightSecond (v) {
                if (v === 'checkAll') {
                    this.$refs.rightTableSecond.selectCurrentPage();
                } else if (v === 'checkNone') {
                    this.$refs.rightTableSecond.unSelectCurrentPage();
                }
            },
            initData () {
                let data = this.initData;

                // this.$refs.leftTable.loadData(data);
                // this.leftCount = data.length;
                this.allData = data;
            },
            leftData () {
                let data = this.leftData;
                this.$refs.leftTable.loadData(data);
                this.leftCount = data.length;

                // this.allData = data;
            },
            rightData () {
                let data = this.rightData;
                this.$refs.rightTable.loadData(data);
                this.rightCount = data.length;
                this.checkedData = data;
            },
            rightDataSecond () {
                let data = this.rightDataSecond;
                this.$refs.rightTableSecond.loadData(data);
                this.rightCountSecond = data.length;
                this.checkedDataSecond = data;
            }
        },
        methods: {
            reset () {

                //将所有数据清空，回到初始状态
                this._clearCheckbox();
                this.leftContainer.clearSelections();
                this.rightContainer.clearSelections();
                this.rightContainerSecond.clearSelections();
                this._disabled2LeftBtn();
                this._disabled2RightBtn();
                this._disabled2LeftBtnSecond();
                this._disabled2RightBtnSecond();
                this._clearRight();
                this._clearRightSecond();
            },
            getJsonValue () {
                let checkNameData = [], 
                    checkNameDataSecond = [];
                if (this.checkedData.length) {
                    checkNameData = this.checkedData.map(item=>item.label);
                };
                if (this.checkedDataSecond.length) {
                    checkNameDataSecond = this.checkedDataSecond.map(item=>item.label);
                }
                let formData = {
                    labelColumns: checkNameDataSecond,
                    trainColumns: checkNameData
                };
                return formData;
            },
             _checkLeftChange () {
                this._disabled2RightBtn(this.getLeftChecked().length === 0);
                this._disabled2RightBtnSecond(this.getLeftChecked().length > 1 || 
                this.checkedDataSecond.length > 0 || this.getLeftChecked().length === 0);
            },
            _checkRightChange () {
                this._disabled2LeftBtn(this.getRightChecked().length === 0);
            },
             _checkRightChangeSecond () {
                this._disabled2LeftBtnSecond(this.getRightCheckedSecond().length === 0);
            },
            _clearRight () {
                let unCheckedData = cloneDeep(this.rightContainer.getAllData());
                this.removeChecked(unCheckedData);
                this._disabled2LeftBtn();
            },
             _clearRightSecond () {
                let unCheckedData = cloneDeep(this.rightContainerSecond.getAllData());
                this.removeCheckedSecond(unCheckedData);
                this._disabled2LeftBtnSecond();
            },

            _clickToLeft () {
                if (this.disabledToLeft) {
                    return;
                }

                let unCheckedData = this.getRightChecked();
                this.removeChecked(unCheckedData);
                this._disabled2LeftBtn();
            },

            _clickToRight () {
                if (this.disabledToRight) {
                    return;
                };
                let checkedData = this.getLeftChecked();
                this.addChecked(checkedData);
                this._disabled2RightBtn();
                this._disabled2RightBtnSecond();
            },
             _clickToLeftSecond () {
                if (this.disabledToLeftSecond) {
                    return;
                }

                let unCheckedData = this.getRightCheckedSecond();
                this.removeCheckedSecond(unCheckedData);
                this._disabled2LeftBtnSecond();
            },

            _clickToRightSecond () {
                if (this.disabledToRightSecond) {
                    return;
                }

                let checkedData = this.getLeftChecked();
                if (checkedData.length > 1) {
                    this.$warn(_('暂时只支持选择一个{0}', this.rightTitleSecond), {autoHide:true});
                    return;
                }
                this.addCheckedSecond(checkedData);
                this._disabled2RightBtn();
                this._disabled2RightBtnSecond();
            },

             /**
             * 添加选中
             * @param {Array | Object} records 列表数据引用
             * @param {Boolean} isRemoveDup 是否去重
             * @private
             */
            addChecked (records, isRemoveDup = true) {
                let idProperty = this.idProperty;

                if (!Array.isArray(records)) {
                    records = [records];
                }

                if (isRemoveDup) { // 去重, 使 records 内部无重复, 并且和 this.checkedData 中间没有交集
                    records = differenceBy(uniqBy(records, idProperty), this.checkedData, idProperty);
                }

                records.forEach(record => {

                    // 如果匹配到的是 String 或者 Number 则视为设置的是 id
                    if (typeof record === 'string' || typeof record === 'number') {
                        record = this.checkedDataMap.get(record);
                    }

                    let isSelected = this.checkedDataMap.has(record[idProperty]);

                    if (!isSelected) {
                        this.checkedData.push(record);
                    }

                    record.selected = false;
                });

                this._updateContainerChecked();
                this.rightContainer.getAllData().forEach(record => record.selected = false);
            },

            /**
             * 移除选中
             * @param {Array | Object} records 列表数据引用
             */
            removeChecked (records) {
                let idProperty = this.idProperty;

                if (!Array.isArray(records)) {
                    records = [records];
                }

                records.forEach(record => {

                    // 如果匹配到的是 String 或者 Number 则视为设置的是 id
                    if (typeof record === 'string' || typeof record === 'number') {
                        record = this.checkedDataMap.get(record);
                    }
                    let index = this.checkedData.findIndex(r => r[idProperty] === record[idProperty]);

                    if (index > -1) {
                        this.checkedData.splice(index, 1);
                    }

                    record.selected = false;
                });

                this._updateContainerChecked();
                this.leftContainer.getAllData().forEach(record => record.selected = false);
            },
            _updateContainerChecked () {

                // 加载右侧容器数据
                this.rightContainer.loadData(this.checkedData);

                // this.leftContainer.setSelections(this.checkedData, true);

                // 加载左侧容器数据。如果配置了穿梭，那么要过滤掉左边表格的数据
                let leftData = [...this.checkedData, ...this.checkedDataSecond];
                let checkedIDs = leftData.map(record => record[this.idProperty]);

                if (this.leftContainer.loadData) {
                    this.leftContainer.loadData(this.allData.filter(record => !checkedIDs.includes(record[this.idProperty])));
                }
                this._clearCheckbox();
                this._updateCount();
            },

             /**
             * 添加选中
             * @param {Array | Object} records 列表数据引用
             * @param {Boolean} isRemoveDup 是否去重
             * @private
             */
            addCheckedSecond (records, isRemoveDup = true) {
                let idProperty = this.idProperty;

                if (!Array.isArray(records)) {
                    records = [records];
                }

                if (isRemoveDup) { // 去重, 使 records 内部无重复, 并且和 this.checkedData 中间没有交集
                    records = differenceBy(uniqBy(records, idProperty), this.checkedDataSecond, idProperty);
                }

                records.forEach(record => {

                    // 如果匹配到的是 String 或者 Number 则视为设置的是 id
                    if (typeof record === 'string' || typeof record === 'number') {
                        record = this.checkedDataMapSecond.get(record);
                    }

                    let isSelected = this.checkedDataMapSecond.has(record[idProperty]);

                    if (!isSelected) {
                        this.checkedDataSecond.push(record);
                    }

                    record.selected = false;
                });

                this._updateContainerCheckedSecond();
                this.rightContainerSecond.getAllData().forEach(record => record.selected = false);
            },

            /**
             * 移除选中
             * @param {Array | Object} records 列表数据引用
             */
            removeCheckedSecond (records) {
                let idProperty = this.idProperty;

                if (!Array.isArray(records)) {
                    records = [records];
                }

                records.forEach(record => {

                    // 如果匹配到的是 String 或者 Number 则视为设置的是 id
                    if (typeof record === 'string' || typeof record === 'number') {
                        record = this.checkedDataMapSecond.get(record);
                    }
                    let index = this.checkedDataSecond.findIndex(r => r[idProperty] === record[idProperty]);

                    if (index > -1) {
                        this.checkedDataSecond.splice(index, 1);
                    }

                    record.selected = false;
                });

                this._updateContainerCheckedSecond();
                this.leftContainer.getAllData().forEach(record => record.selected = false);
            },
            _updateContainerCheckedSecond () {

                // 加载右侧容器数据
                this.rightContainerSecond.loadData(this.checkedDataSecond);

                // this.leftContainer.setSelections(this.checkedDataSecond, true);

                // 加载左侧容器数据。如果配置了穿梭，那么要过滤掉左边表格的数据
                let leftData = [...this.checkedData, ...this.checkedDataSecond];
                let checkedIDs = leftData.map(record => record[this.idProperty]);

                if (this.leftContainer.loadData) {
                    this.leftContainer.loadData(this.allData.filter(record => !checkedIDs.includes(record[this.idProperty])));
                }
                this._clearCheckbox();
                this._updateCount();
            },


            _disabled2LeftBtn (isDisabled = true) {
                this.disabledToLeft = isDisabled;
            },

            _disabled2RightBtn (isDisabled = true) {
                this.disabledToRight = isDisabled;
            },
            _disabled2LeftBtnSecond (isDisabled = true) {
                this.disabledToLeftSecond = isDisabled;
            },

            _disabled2RightBtnSecond (isDisabled = true) {
                this.disabledToRightSecond = isDisabled;
            },

            /**
             * 获取左边容器选中的数据
             * @returns {Array}
             * */
            getLeftChecked () {
                return extend(this.leftContainer.getSelections());
            },

            /**
             * 获取右边容器选中的数据
             * @returns {Array}
             * */
            getRightChecked () {
                return extend(this.rightContainer.getSelections());
            },
            getRightCheckedSecond () {
                return extend(this.rightContainerSecond.getSelections());
            },
             _updateCount () {
                this.leftCount = this.leftContainer.getAllData().length;
                this.rightCount = this.rightContainer.getAllData().length;
                this.rightCountSecond = this.rightContainerSecond.getAllData().length;
            },

            _clearCheckbox () {
                this.checkAllLeft = 'checkNone';
                this.checkAllRight = 'checkNone';
                this.checkAllRightSecond = 'checkNone';
            }

        }
    };

</script>
